/* Wasson An
 * This class contains the panel on which the game is played for single player. 
 * The panel also runs the whole game.	
 */

package catandmouse;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.JOptionPane;


public class SingleGamePanel implements CAM, ActionListener{

	private final int SPEED = 5; //the speed
	private final double ACCEL = .12; //acceleration

	private Timer timer; //the timer used to run the game
	private Actor mouse; //the mouse
	private Actor cat; //the cat
	private boolean up; //if the mouse is going up
	private boolean down; //if the mouse is going down
	private boolean left; //if the mouse is going left
	private boolean right; //if the mouse is going right
	private double mvSpeed; //mouse vertical speed
	private double mhSpeed; //mouse horizontal speed
	private double count; //how many cycles you stayed alive
	private double diff; //the difficulty

	JFrame game;
	GamePanel gamePanel;

	//0 parameter constructor creating and running the game
	public SingleGamePanel(){

		diff = 5;

		game = new JFrame();
		game.setSize(1000, 720);
		game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	    game.setVisible(true);		
		this.start();
	}//default constructor


	//starts the game
	public void start(){

		//resets movement flags
		up = false;
		down = false;
		left = false;
		right = false;
		mvSpeed = 0;
		mhSpeed = 0;

		//sets up the initial timer
		timer = new Timer(10, this);
		timer.setInitialDelay(1000);
		timer.setRepeats(true);
		count = 0;

		//places the player and cat
		int w =	game.getWidth();
		int h = game.getHeight();

		cat = new Actor(w / 3, h / 2, w, h);
		mouse = new Actor(2 * w / 3, h / 2, w, h);
		
		game.repaint();
		
		gamePanel = new GamePanel(mouse.getPosition(), cat.getPosition(), this,
				w, h);
		game.add(gamePanel);
		gamePanel.repaint();
		game.repaint();
		
		//asks for difficulty and starts the game
		String d =JOptionPane.showInputDialog("Please input a difficulty" +
				" greater than -10.\nA diffiulty of 5 is recommended.", diff);

		diff = Double.parseDouble(d);

		JOptionPane.showMessageDialog(null, "Press OK to play. Game will " +
				"start in one second.");

		timer.start();
	}//start


	//triggered when the timer ticks
	public void actionPerformed(ActionEvent e) {

		count++;

		//moves the mouse
		if(down)
			mvSpeed += ACCEL;

		if(up)
			mvSpeed -= ACCEL;

		if(left)
			mhSpeed -= ACCEL;

		if(right)
			mhSpeed += ACCEL;
		
		if(mvSpeed < 0)
			mvSpeed += ACCEL / 3;
		
		else
			mvSpeed -= ACCEL / 3;
		
		if(mhSpeed < 0)
			mhSpeed += ACCEL / 3;
			
		else
			mhSpeed -= ACCEL / 3;
		

		if(mvSpeed > SPEED)
			mvSpeed = SPEED;

		if(mhSpeed > SPEED)
			mhSpeed = SPEED;

		if(mvSpeed < SPEED * -1)
			mvSpeed = SPEED * -1;

		if(mhSpeed < SPEED * -1)
			mhSpeed = SPEED * -1;

		mouse.moveHorizontal((int)Math.round(mhSpeed));
		mouse.moveVertical((int)Math.round(mvSpeed));

		//moves the cat
		int xDiff = mouse.getPosition().getX() - cat.getPosition().getX();
		int yDiff = mouse.getPosition().getY() - cat.getPosition().getY();
		int hDiff = xDiff;
		int vDiff = yDiff;
		
		double difference = Math.abs(hDiff) + Math.abs(vDiff);
		double distance = Coordinate.distance(new Coordinate(0, 0),
				new  Coordinate(hDiff, vDiff));
		double time = distance / SPEED;
		
		hDiff += mhSpeed * time * 2;
		vDiff += mvSpeed * time * 2;
		

		cat.moveHorizontal((int)Math.round(((1 + (diff / 10)) *
				(SPEED + count / 500) * (hDiff / difference))));
		cat.moveVertical((int)Math.round(((1 + (diff / 10)) * 
				(SPEED + count / 500) * (vDiff / difference))));

		//refreshes the screen
		gamePanel.setMPos(mouse.getPosition());
		gamePanel.setCPos(cat.getPosition());
		gamePanel.setCount(count);
		gamePanel.repaint();

		//checks if you lost
		if(Math.abs(xDiff) < 10 && Math.abs(yDiff) < 10){

			timer.stop();

			//score and asks if the player wants to play again
			int c = JOptionPane.showConfirmDialog(null, "You stayed alive " +
					"for " + count / 100 + " seconds.\nDifficulty was " + diff
					+ "\nPlay again?");

			if(c == JOptionPane.YES_OPTION){
				
				game.remove(gamePanel);
				gamePanel = null;
				this.start();
			}//if
			
			else
				System.exit(0);			
		}//if
	}//actionPerformed


	//when a key is pressed down
	public void keyPressed(KeyEvent e){

		if(e.getKeyCode() == KeyEvent.VK_UP)		
			up = true;

		else if(e.getKeyCode() == KeyEvent.VK_DOWN)
			down = true;

		else if(e.getKeyCode() == KeyEvent.VK_LEFT)
			left = true;

		else if(e.getKeyCode() == KeyEvent.VK_RIGHT)
			right = true;
	}//keyPressed


	//when a key is released
	public void keyReleased(KeyEvent e){

		if(e.getKeyCode() == KeyEvent.VK_UP)
			up = false;

		else if(e.getKeyCode() == KeyEvent.VK_DOWN)
			down = false;

		else if(e.getKeyCode() == KeyEvent.VK_LEFT)
			left = false;

		else if(e.getKeyCode() == KeyEvent.VK_RIGHT)
			right = false;
	}//keyPressed


	//when a key is typed
	public void keyTyped(KeyEvent arg0) {

	}//keyTyped
	
	
	public static void main(String[] args){
		
		new SingleGamePanel();
	}//main
}//GamePanel
